/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.common.reflect;

import java.lang.reflect.Type;

import static org.vacoor.nothing.common.reflect.TypeResolver.resolveActualTypeArguments;

/**
 * 泛型类工具类
 * 用于获取泛型类的相应的类型参数
 * <p/>
 * 1. 运行时指定
 * <pre>
 *   class A&lt;T&gt; extends GenericBeanSupport&lt;T&gt; {}
 *   new A&lt;String&gt;()  --> getActualTypeArgument() == String.class
 * </pre>
 * 2. 多级继承直接指定
 * <pre>
 *   abstract class B&lt;T, E&gt; extends GenericBeanSupport&lt;T&gt; {}
 *   class C extends B&lt;String,Integer&gt; {}
 *   new C()  --> getActualTypeArgument() == String.class
 * </pre>
 * 3. 多级继承传递运行时指定
 * <pre>
 *    class D&lt;T&gt; extends B&lt;T, String&gt; {}
 *    new D&lt;Integer&gt;() --> getActualTypeArgument() == Integer.class
 * </pre>
 *
 * @author vacoor
 */
public abstract class GenericBeanSupport<T> {
    private Class<T> actualTypeArgument;

    /**
     * 获取当前泛型类的泛型参数, 如果不是一个Class对象将抛出{@link java.lang.IllegalStateException}
     *
     * @return 泛型参数T的Class对象
     */
    @SuppressWarnings("unchecked")
    protected final Class<T> getActualTypeArgument() {
        if (actualTypeArgument != null) {
            return actualTypeArgument;
        }

        Type typeArg = resolveActualTypeArguments(getClass(), GenericBeanSupport.class, 0);
        if (null == typeArg) {
            throw new IllegalStateException("Internal error: without actual type information");
        }

        if (!(typeArg instanceof Class)) {
            throw new IllegalStateException("Internal error: type parameter must be a certain type");
        }
        return actualTypeArgument = (Class<T>) typeArg;
    }

    protected GenericBeanSupport() {}
}
